package org.upfrost;

import java.sql.SQLException;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.junit.Before;
import org.junit.Test;
import org.upfrost.Mapper;
import org.upfrost.MapperSession;
import org.upfrost.mapping.classes.TestClass2;
import org.upfrost.mapping.classes.TestClass2DAO;
import org.upfrost.mapping.classes.TestClass3;

import com.mchange.v2.c3p0.ComboPooledDataSource;


public class MapperSessionTest extends TestCase
{
	private Mapper m_mapper;

	@Before
	public void setUp() throws Exception 
	{
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		dataSource.setDriverClass("org.hsqldb.jdbcDriver");
		dataSource.setJdbcUrl("jdbc:hsqldb:mem:test");
		dataSource.setUser("sa");
		dataSource.setPassword("");
		
		m_mapper = new Mapper(dataSource);
		m_mapper.addAnnotated(TestClass2.class, TestClass3.class);
	}

	@Test
	public void testSessionInit()
	{
		try {
			MapperSession session = m_mapper.getSession();
			Assert.fail(); // Uninitialized session must fail
		} catch (Exception exc)
		{
			// Ignore
		}
		
		MapperSession session = m_mapper.initSession("test").getSession();
		Assert.assertNotNull(session);
	}

	@Test
	public void testSessionClose()
	{
		MapperSession session = m_mapper.initSession("test").getSession();
		Assert.assertNotNull(session);

		session.close();
		
		try {
			MapperSession session2 = m_mapper.getSession();
			Assert.fail(); // Uninitialized session must fail
		} catch (Exception exc)
		{
			// Ignore
		}
		
	}

	
	@Test
	public void testSessionSaveRestore() throws SQLException
	{
		MapperSession session = m_mapper.initSession("test").getSession();
		Assert.assertNotNull(session);

		boolean orgAutoCommit = session.getAutoCommit();
		boolean orgCacheEnabled = session.isCacheEnabled();
		
		session.saveState();
		session.setAutoCommit(!orgAutoCommit);
		session.setCacheEnabled(!orgCacheEnabled);
		
		Assert.assertEquals(!orgAutoCommit, session.getAutoCommit());
		Assert.assertEquals(!orgCacheEnabled, session.isCacheEnabled());
		
		session.restoreState();
		Assert.assertEquals(orgAutoCommit, session.getAutoCommit());
		Assert.assertEquals(orgCacheEnabled, session.isCacheEnabled());
	}

	@Test
	public void testSessionSaveRestoreMultiple() throws SQLException
	{
		MapperSession session = m_mapper.initSession("test").getSession();
		Assert.assertNotNull(session);

		boolean orgAutoCommit = session.getAutoCommit();
		boolean orgCacheEnabled = session.isCacheEnabled();
		
		session.saveState();
		session.setAutoCommit(!orgAutoCommit);
		session.setCacheEnabled(!orgCacheEnabled);
		Assert.assertEquals(!orgAutoCommit, session.getAutoCommit());
		Assert.assertEquals(!orgCacheEnabled, session.isCacheEnabled());

		session.saveState();
		session.setAutoCommit(orgAutoCommit);
		session.setCacheEnabled(orgCacheEnabled);
		Assert.assertEquals(orgAutoCommit, session.getAutoCommit());
		Assert.assertEquals(orgCacheEnabled, session.isCacheEnabled());
		
		session.restoreState();
		Assert.assertEquals(!orgAutoCommit, session.getAutoCommit());
		Assert.assertEquals(!orgCacheEnabled, session.isCacheEnabled());
		
		session.restoreState();
		Assert.assertEquals(orgAutoCommit, session.getAutoCommit());
		Assert.assertEquals(orgCacheEnabled, session.isCacheEnabled());
	}

	@Test
	public void testCacheDisabled()
	{
		MapperSession session = m_mapper.initSession("test").getSession();
		Assert.assertNotNull(session);

		session.setCacheEnabled(false);
		TestClass2DAO tc2dao = new TestClass2DAO(session);
		session.getCache().write(tc2dao, "result1", "query1", "param1");
	}
	
}
